package net.lcqf.udp.server;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import io.netty.buffer.ByteBuf;
import net.lcqf.udp.base.fec.Snmp;
import net.lcqf.udp.kcp.ChannelConfig;
import net.lcqf.udp.kcp.KcpListener;
import net.lcqf.udp.kcp.KcpServer;
import net.lcqf.udp.kcp.Ukcp;
import net.lcqf.udp.send.MessageFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * +----------------------------------------------------------------------
 * // | Talk To [ 聊来改善地区金融服务环境，助力企业发展 ]
 * // +----------------------------------------------------------------------
 * // | Copyright (c) 2021-2025 聊来 All rights reserved.
 * // +----------------------------------------------------------------------
 * // | Licensed ( <a href="http://www.apache.org/licenses/LICENSE-2.0">apache</a> )
 * // +----------------------------------------------------------------------
 * // | @Author: 聊来 <18970881148@qq.com>
 * // +----------------------------------------------------------------------
 * // | DateTime: 2025/2/12 14:20
 * // +----------------------------------------------------------------------
 */

@Component
public class UdpServer implements KcpListener {
    private final Logger logger = LoggerFactory.getLogger(UdpServer.class);

    private final MessageFactory messageFactory;

    public void start(int port) {
        UdpServer udpServer = new UdpServer(messageFactory);

        ChannelConfig channelConfig = new ChannelConfig();
        channelConfig.setUseConvChannel(true);
        channelConfig.nodelay(true,5,2,true);
        channelConfig.setSndwnd(64);
        channelConfig.setRcvwnd(64);
        channelConfig.setMtu(1200);
        //channelConfig.setConv(168);
        channelConfig.setAckNoDelay(true);
        channelConfig.setTimeoutMillis(15000);
        //channelConfig.setFecDataShardCount(10);
        //channelConfig.setFecParityShardCount(3);
        //c# crc32未实现
        channelConfig.setCrc32Check(false);
        KcpServer kcpServer = new KcpServer();
        kcpServer.init(udpServer,channelConfig,port);
    }

    public UdpServer(MessageFactory messageFactory) {
        this.messageFactory = messageFactory;
    }

    @Override
    public void onConnected(Ukcp kcp) {
        logger.info("有连接进来：{}，kcp信息：{}", Thread.currentThread().getName(), kcp.toString());
    }

    @Override
    public void handleReceive(ByteBuf buf, Ukcp kcp) throws IOException {
        byte[] bytes = new byte[buf.readableBytes()];
        buf.getBytes(buf.readerIndex(), bytes);
        //logger.info("收到消息: {} - 发送的消息人：{}",new String(bytes), kcp.getConv());

        MsgInfo msgInfo = JSONUtil.toBean(new String(bytes), MsgInfo.class);
        //logger.info("接收客户端发送的消息：{}，kcp信息：{}", msgInfo, kcp.toString());
        Object data = messageFactory.sendMessage(kcp, msgInfo);
        if (ObjectUtil.isNotNull(data)) {
            msgInfo.setData(JSONUtil.toJsonStr(data));


            ByteBuf byteBuf = MessageFactory.serializeToByteBuf(JSONUtil.toJsonStr(msgInfo));
            kcp.write(byteBuf);
            byteBuf.release();
        }
    }

    @Override
    public void handleException(Throwable ex, Ukcp kcp) {
        logger.error("消息异常：" + ex.getMessage());
        ex.printStackTrace();
    }

    @Override
    public void handleClose(Ukcp kcp) {
        logger.warn(Snmp.snmp.toString());
        Snmp.snmp  = new Snmp();
        logger.warn("kcp：{}", kcp.toString());
    }
}
